﻿using System;
using System.Threading;

namespace LibraryGuard
{
	static class Program
	{
		#region Logger
		private static NLog.Logger Logger = NLog.LogManager.GetLogger("Main");
		#endregion

		/// <summary>
		/// Main method.
		/// </summary>
		private static void Main()
		{
			Logger.Info("Program started");

			var cfg = new ConfigLoader();
			if (!cfg.ParseArguments())
			{
				Environment.ExitCode = -1;
				return;
			}

			if (cfg.Service)
				RunAsAService(cfg);
			else
				Environment.ExitCode = RunNormal(cfg);

			Logger.Info("Exiting");
		}

		/// <summary>
		/// Runs as normal program.
		/// </summary>
		private static int RunNormal(ConfigLoader cfg)
		{
			var actionList = new ActionList();
			if (!cfg.Run(actionList))
				return -2;

			using (var execution = new EventWaitHandle(!cfg.Configuration.Continuous, EventResetMode.ManualReset))
			using (var continuous = cfg.Configuration.Continuous ? new Utilities.ContinuousMode(cfg.Configuration, cfg.Guards) : null)
			using (var mode = Modes.Factory.CreateMode(cfg.Configuration, cfg.Guards, actionList))
			{
				Console.WriteLine("Press Ctrl+C to stop program");
				if (cfg.Configuration.Continuous)
				{
					Console.CancelKeyPress += (s, e) =>
						{
							e.Cancel = true;
							execution.Set();
						};
				}
				//CONSIDER: How to support Ctrl+C in normal mode

				if (cfg.Configuration.Continuous)
					continuous.Run();

				Utilities.Scheduler scheduler = null;
				if (cfg.Configuration.Continuous && cfg.Configuration.DueTime != TimeSpan.Zero)
				{
					scheduler = new Utilities.Scheduler(mode, new TimeSpan(0, 0, 10), new TimeSpan(0, 0, 20));
					scheduler.Start();
				}
				else
					mode.Start();
				execution.WaitOne();
				if (scheduler != null)
					scheduler.Stop();
				mode.Stop(cfg.Configuration.Continuous);
			}
			return 0;
		}

		/// <summary>
		/// Runs as service.
		/// </summary>
		/// <param name="cfg"></param>
		private static void RunAsAService(ConfigLoader cfg)
		{
			System.ServiceProcess.ServiceBase.Run(new LibraryGuardService(cfg));
		}
	}
}
